MobX 7#4671
Conversation
🦋 Changeset detectedLatest commit: 30eef8f The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
amazing ✨🚀 thank you for working on this :) |
If MST doesn't use it anymore (that is what is was introduced for), I think we could drop the feature just altogether. At it's core it is a feature that should imho be solved in userland, not inside the library, and it will remove a bunch of indirection / inefficiency in how values are processed. |
|
The other changes look great! |
|
Beyond that LGTM! Happy to help with further merge and release / version number coordination. Not surely entirely how I did that with previous majors, but muscle memory will hopefully return when going through the motions :). So let me know when you're happy @kubk and I can merge & cut. |
|
@mweststrate Thanks! It does seem that ObservableValue.enhancer can be removed, but I won’t be able to find the time to properly clean it up in the next couple of weeks and I don't want that to become a blocker for the v7 release. So if the rest looks ok, please proceed with the merge and the beta release! Also I was hoping we could get the minimal MobX example to ~10 kB gzip (a beautiful number!) I tried many different approaches to reduce the output size. Some helped, some didnt and at this point I'm out of ideas If you see any obvious size wins, i'd really appreciate your help there too. There's |
|
I have some obligations this week I can't get around, but happy to circle back to this next week! |
|
The tree-shaken Mobx is now down to 10.3 kb gzip 🥳 Hope this round of optimizations is the last one! It might seem like a lot but it's actually all about moving / removing things. Optimizations:
*By "intercept / observe partially excluded" I mean:
I also analyzed how the function enhanceValue(
enhancer: Enhancer,
newValue,
oldValue,
name
) {
switch (enhancer) {
case Enhancer.Deep: return deepEnhancer(...);
case Enhancer.Ref: return newValue;
case Enhancer.Shallow: return shallowEnhancer(...);
case Enhancer.Struct: return refStructEnhancer(newValue, oldValue, name)
}
}And that will increases the bundle size from 10.32 kb to 10.86 kb gzip (because all of the enhancers are included). Please let me know if anything is missing here! As for "improving efficiency" it seems like just merging #4683 will already provide a lot of value To summarize i'd really appreciate your help with 2 things:
Thank you! |
|
@kubk I just realized I misnomed, meant dehancer instead of enhancer. My current thinking is (I have some WIP changes for this, can keep pushing on this). All disputable
What do you, and others, think? |
|
From an end user's point of view, I think removing those APIs seems great.
I've used intercept once or twice, but there were always other ways to
handle the same issue.
I'm excited to see where Mobx 7 ends up!
…On Mon, Jul 13, 2026 at 1:53 AM Michel Weststrate ***@***.***> wrote:
*mweststrate* left a comment (mobxjs/mobx#4671)
<#4671 (comment)>
@kubk <https://github.com/kubk> I just realized I misnomed, meant
dehancer instead of enhancer. My current thinking is (I have some WIP
changes for this, can keep pushing on this). All disputable
1. Remove dehancer, ObservableValue.raw (this locks MST to the
previous major I think, I'm not entirely sure if it can work without these
two backdoors? unless it is fully proxy based now)
2. Remove intercept / observe. These two functions exist to make MobX
some sort of swiss army knife of an higher order abstract library to
basically provide default proxy trap patterns to the core JS collections
Object/Map/Array/Set. I think this however goes in principle outside the
scope of MobX and they don't really belong inside MobX, as they don't do
anything with reactivity. If people wanted to do this kind of object
trapping, nowadays they can just directly proxy wrap themselves.
3. Remove spy, and getDebugName and the observer tree utilities (even
though they mostly fall outside of bundling anyway). It is all quite a lot
of code, and I'm not really sure people really use it for debugging, since
it requires code changes. Well placed console.logs / breakpionts and
following idiomatic patterns should be sufficient to debug MobX? And in a
world of increasing agentic development, I think there is less and less
need to expose those utilities to make it possible to build rich debug
tools.
4. Remove all the object-api's, keys, values, entries, these are
remnants of the pre Proxy world, where these offered a work around to
reactively read / observe otherwise unobservable object mutations.
5. toJS might arguable belong better in mobx-utils, but I'm a little
reluctant to remove it for I don't know which reason :)
6. Several of the _ prefixed APIs exposed in mobx. I'm not sure any
should be exposed, outside the ones used for tests (and there might be a
better way to set that up).
What do you, and others, think?
—
Reply to this email directly, view it on GitHub
<#4671?email_source=notifications&email_token=AABCW4SD7XSHEWHWA4XUUML5ESBQNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOJVGUZDGOBQGIY2M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSWGM33PORSXEX3DNRUWG2Y#issuecomment-4955238021>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABCW4QVJM2NPCZKDUQK6YL5ESBQNAVCNFSNUABEKJSXA33TNF2G64TZHMZTEMRRGU4TOMB3JFZXG5LFHM2DMMRUGAYDIMBSGWQXMAQ>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AABCW4UQ7UVSKJAE3NCMCYL5ESBQNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOJVGUZDGOBQGIY2M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSVGM33PORSXEX3JN5ZQ>
and Android
<https://github.com/notifications/mobile/android/AABCW4UJXPC2N474GOT2RXD5ESBQNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOJVGUZDGOBQGIY2M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSXGM33PORSXEX3BNZSHE33JMQ>.
Download it today!
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
--
-Matt Ruby-
***@***.***
|
|
@mweststrate I'm totally up for this direction. A few notes on each point
1-2 - I haven't used MST or mobx-keystone myself but it seems like they both use 3 - I wouldn't mind removing the current spy / getDebugName. AI assisted debugging makes temporary instrumentation much cheaper now. An agent can add the relevant console.logs and inspect the result through Chrome MCP. Yet, 4 - Makes total sense 5 - toJS is already completely tree-shaken, so maybe it's not enough by itself to justify moving such a commonly used API 6 - I am also up for cleaning this up, where possible. MST is still using a couple of such functions like |
|
@kubk - from what I can see, we use My goal with the library has been to prioritize stability, so I'd personally vote against the removal from MobX, purely from the stance that I try to avoid making changes to MST these days. But with AI, it's not a huge burden for me to reimplement these functions in MST. We have pretty thorough test suites that should make the transition smooth. |
|
It would be cool to have a |
|
Thanks for the heads up! mobx-keystone relies on both APIs for core tree semantics:
I checked MST as well: its model, array, and map types use the same intercept / observe funcs for writable checks, child reconciliation, and patch emission. The current tree-shaking improvement looks great, but removing these APIs outright would be a breaking change for both libraries unless there is a supported replacement with equivalent synchronous pre-commit interception and structured post-commit change events. reaction alone would not be equivalent, since it runs after the mutation and does not provide the same change payload. If there is an alternative API or a separate opt-in module in mind, I’d be happy to test mobx-keystone against it and help validate a migration path. |
|
@coolsoftwaretyler , @jamonholmgren , @xaviergonz Hi! thanks for piling in. Some thoughts:
|
|
Not that it's my place to speak, but as an end user, I had always wished for mobx' API surface to become a bit leaner and more constrained in what mobx offers vs. what external packages should handle And it is a new major, after all. I would not be terribly unhappy with a breaking change of this sort So, as an end user, I'd love to see intercept/observe moved out |
|
@mweststrate I am also up for the leanest possible Mobx - no intercept/observe, no debug utilities, no decorators (in the core package), minimum options inside But MST/mobx-keystone have ~200k weekly downloads combined so locking them to the outdated Mobx 6 seems like a miss What if we
The reason i suggest 7 and 8 instead of 6 and 7 is because v6 carries a ton of legacy. And if we're going to support 2 mobx versions anyway, we might as well make the older one the cleaned up v7 instead of carrying all of v6 indefinitely |
#3796
StubArrayworkaround is incompatible with terser'sunsafe_arrowsoption #3825compare*as well asflow.*/action.*intoflow*/action*etc for better tree-shaking: Add computed.shallow annotation #2986observe/interceptpartial tree-shaking*minimal only exports observable, action, computed, and autorun. All the measurement scripts are in the PR.
I also tried a more aggressive change - removing decorators from the main bundle entirely and moving them into a separate
mobx/decoratormodule. To my surprise, that only saved about 0.8 KB gzippedYet this required a pretty serious overhaul of the library internals, and I'm not sure it is stable enough to release. Considering the very modest gains, I called this out. The PR doesn't include it.
In general the V7 should be pretty safe to migrate to, as it's mostly cleanup